﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Reflection;

namespace Cmd.Internal
{
    internal enum AssemblyInfoSpec
    {
        CompanyName,
        CopyrightHolder,
        Description,
        ProductName,
        Title,
        Version
    }

    internal static class Extensions
    {
        internal static IEnumerable<string> Split(this string value, int maxLength, StringSplitOptions options)
        {
            IEnumerable<string> splittedValue = Split(value, maxLength);

            if (options == StringSplitOptions.RemoveEmptyEntries)
            {
                foreach (string val in splittedValue)
                {
                    if (string.IsNullOrEmpty(val))
                    {
                        continue;
                    }
                    yield return val;
                }

            }
            else
            {
                foreach (string val in splittedValue)
                {
                    yield return val;
                }
            }
        }

        internal static IEnumerable<string> Split(this string value, int maxLength)
        {
            if (string.IsNullOrEmpty(value))
            {
                yield return value;
            }

            int index = 0;
            while (index + maxLength <= value.Length)
            {
                yield return value.Substring(index, maxLength);
                index += maxLength;
            }

            yield return value.Substring(index);

        }

        internal static string Multiply(this string source, int multiplier)
        {
            StringBuilder sb = new StringBuilder(multiplier * source.Length);
            for (int i = 0; i < multiplier; i++)
            {
                sb.Append(source);
            }

            return sb.ToString();
        }

        internal static string GetAssemblyInfo(this Assembly assembly, AssemblyInfoSpec spec)
        {
            object[] attributes = null;
            switch (spec)
            {
                case AssemblyInfoSpec.CompanyName:
                    attributes = assembly.GetCustomAttributes(typeof(AssemblyCompanyAttribute), false);
                    return attributes.Length == 0 ? null : ((AssemblyCompanyAttribute)attributes[0]).Company;
                case AssemblyInfoSpec.CopyrightHolder:
                    attributes = assembly.GetCustomAttributes(typeof(AssemblyCopyrightAttribute), false);
                    return attributes.Length == 0 ? null : ((AssemblyCopyrightAttribute)attributes[0]).Copyright;
                case AssemblyInfoSpec.Description:
                    attributes = assembly.GetCustomAttributes(typeof(AssemblyDescriptionAttribute), false);
                    return attributes.Length == 0 ? null : ((AssemblyDescriptionAttribute)attributes[0]).Description;
                case AssemblyInfoSpec.ProductName:
                    attributes = assembly.GetCustomAttributes(typeof(AssemblyProductAttribute), false);
                    return attributes.Length == 0 ? null : ((AssemblyProductAttribute)attributes[0]).Product;
                case AssemblyInfoSpec.Title:
                    attributes = assembly.GetCustomAttributes(typeof(AssemblyTitleAttribute), false);
                    if (attributes.Length > 0)
                    {
                        AssemblyTitleAttribute titleAttribute = (AssemblyTitleAttribute)attributes[0];
                        if (titleAttribute.Title.Length > 0)
                        {
                            return titleAttribute.Title;
                        }
                    }
                    return System.IO.Path.GetFileNameWithoutExtension(Assembly.GetExecutingAssembly().CodeBase);
                case AssemblyInfoSpec.Version:
                    Version v = assembly.GetName().Version;
                    return string.Format("{0}.{1}", v.Major, v.Minor);
                default:
                    break;
            }
            return null;
        }

    }
}
